//
// Created by madison on 2022/1/12.
//

// 多态
#include <iostream>

using namespace std;


class Shape {
protected:
    int width, height;
public:
    Shape(int a = 0, int b = 0) {
        width = a;
        height = b;
    }

    // 但现在，让我们对程序稍作修改，在 Shape 类中，area() 的声明前放置关键字 virtual
    virtual int area() {
        cout << "Parent class area :";
        return 0;
    }

    // pure virtual function
    /**
     *  虚函数
        虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时，会告诉编译器不要静态链接到该函数。

        我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数，这种操作被称为动态链接，或后期绑定。

        纯虚函数
        您可能想要在基类中定义虚函数，以便在派生类中重新定义该函数更好地适用于对象，但是您在基类中又不能对虚函数给出有意义的实现，这个时候就会用到纯虚函数。

        我们可以把基类中的虚函数 area() 改写如下：
     * @return
     */
    //    virtual int area() = 0;
};

class Rectangle : public Shape {
public:
    Rectangle(int a = 0, int b = 0) : Shape(a, b) {}

    int area() {
        cout << "Rectangle class area :";
        return (width * height);
    }
};

class Triangle : public Shape {
public:
    Triangle(int a = 0, int b = 0) : Shape(a, b) {}

    int area() {
        cout << "Triangle class area :";
        return (width * height / 2);
    }
};

int main() {
    Shape *shape;
    Rectangle rec(10, 7);
    Triangle tri(10, 5);

    // 存储矩形的地址
    shape = &rec;
    // 调用矩形的求面积函数 area
    cout << shape->area() << endl;


    // 存储三角形的地址
    shape = &tri;
    // 调用三角形的求面积函数 area
    cout << shape->area() << endl;

    return 0;
}